Micron Document
πŸŽ–οΈGitΠ―Ρ€Π°πŸŽ–οΈ


Displaying Rendered β€’ View raw β€’ Download

.skills/testing-ci/SKILL.md d4eadee500c39e2e09f352a385ee7f3b2bd1a79f (d4eadee5) Text, 6.70 KB

Skill: Testing and CI Verification

Description
Guidelines and commands for verifying code changes locally and understanding the Meshtastic-Android CI pipeline. Use this to determine which testing matrix is needed based on the change type.

1) Baseline local verification order

Run in a single invocation for routine changes to ensure code formatting, analysis, and basic compilation:

T282828
./gradlew spotlessCheck spotlessApply detekt assembleDebug Tffa657test allTests


β”‚ Why no T383838clean? Incremental builds are safe and significantly faster. Only use T383838clean when debugging
β”‚ stale cache issues.

β”‚ Why T383838test allTests and not just T383838test: In KMP modules, the T383838test task name is ambiguous. Gradle
β”‚ matches both T383838testAndroid and T383838testAndroidHostTest and refuses to run either, silently skipping KMP
β”‚ modules. T383838allTests is the T383838KotlinTestReport lifecycle task registered by the KMP plugin.
β”‚ Conversely, T383838allTests does not cover pure-Android modules (T383838:app, T383838:core:api, etc.), which is why
β”‚ both T383838test and T383838allTests are needed.

Note: If testing Compose UI on the JVM (Robolectric) with Java 21, pin tests to T383838@Config(sdk = [34]) to avoid SDK 35 compatibility crashes.

2) Change-type verification matrix

β€’ T383838docs-only changes: Usually no Gradle run required, but run T383838spotlessCheck if practical.
β€’ T383838UI text/resource changes: T383838spotlessCheck, T383838detekt, T383838assembleDebug.
β€’ T383838feature/commonMain logic changes: T383838spotlessCheck, T383838detekt, T383838test allTests, T383838assembleDebug.
β€’ T383838navigation/DI wiring changes: T383838spotlessCheck, T383838detekt, T383838assembleDebug, T383838test allTests, plus flavor unit tests if available.
β€’ If touching any KMP module, also run T383838kmpSmokeCompile.
β€’ T383838worker/service/background changes: Broad tests, targeted WorkManager checks.
β€’ T383838BLE/networking/core repository: T383838spotlessCheck, T383838detekt, T383838assembleDebug, T383838test allTests.

3) Flavor checks

Run these when relevant to map, provider, or flavor-specific behavior:

T282828
./gradlew lintFdroidDebug lintGoogleDebug
./gradlew testFdroidDebug testGoogleDebug

4) CI Pipeline Architecture

CI is defined in T383838.github/workflows/reusable-check.yml and structured as four parallel job groups:

1. T383838lint-check β€” Runs spotless, detekt, Android lint, and KMP smoke compile in a single Gradle invocation (avoids 3x cold-start overhead). Uses T383838fetch-depth: 0 (full clone) for spotless ratcheting and version code calculation. Produces T383838cache_read_only output and computed T383838version_code for downstream jobs.
2. T383838test-shards β€” A 3-shard matrix that runs unit tests in parallel (depends on T383838lint-check):
β€’ T383838shard-core: T383838allTests for all T383838core:* KMP modules.
β€’ T383838shard-feature: T383838allTests for all T383838feature:* KMP modules.
β€’ T383838shard-app: Explicit test tasks for pure-Android/JVM modules (T383838app, T383838desktop, T383838core:barcode).
Each shard generates Kover XML coverage and uploads test results + coverage to Codecov with per-shard flags.
Downstream jobs use T383838fetch-depth: 1 and receive T383838VERSION_CODE from lint-check via env var, enabling shallow clones.
3. T383838android-check β€” Builds APKs for all flavors (depends on T383838lint-check).
4. T383838build-desktop β€” Multi-OS matrix (T383838macos-latest, T383838windows-latest, T383838ubuntu-24.04, T383838ubuntu-24.04-arm) that builds desktop distributions via T383838createDistributable (depends on T383838lint-check).

Runner Strategy (Three Tiers)
β€’ T383838ubuntu-24.04-arm β€” Lightweight/utility jobs (status checks, labelers, triage, changelog, release metadata, stale, moderation). Benefits from ARM runners' shorter queue times.
β€’ T383838ubuntu-24.04 β€” Main Gradle-heavy jobs (CI T383838lint-check/T383838test-shards/T383838android-check, release builds, Dokka, publish, dependency-submission). Pin for reproducibility.
β€’ Desktop runners: Multi-OS matrix (T383838macos-latest, T383838windows-latest, T383838ubuntu-24.04, T383838ubuntu-24.04-arm) for the T383838build-desktop job and release packaging.

CI Gradle Properties
T383838gradle.properties is tuned for local dev (8g heap, 4g Kotlin daemon). CI uses T383838.github/ci-gradle.properties, which the T383838gradle-setup composite action copies to T383838~/.gradle/gradle.properties. Key CI overrides:
β€’ T383838org.gradle.daemon=false (single-use runners)
β€’ T383838kotlin.incremental=false (fresh checkouts)
β€’ T383838-Xmx4g Gradle heap, T383838-Xmx2g Kotlin daemon
β€’ VFS watching disabled, workers capped at 4
β€’ T383838org.gradle.isolated-projects=true for better parallelism
β€’ Disables unused Android build features (T383838resvalues, T383838shaders)

CI Conventions
β€’ KMP Smoke Compile: T383838./gradlew kmpSmokeCompile is a lifecycle task (registered in T383838RootConventionPlugin) that auto-discovers all KMP modules and depends on their T383838compileKotlinJvm + T383838compileKotlinIosSimulatorArm64 tasks.
β€’ T383838maxParallelForks CI logic: T383838ProjectExtensions.kt checks T383838project.findProperty("ci") == "true" and uses full available processors in CI (4 forks on std runners) vs. half locally. All CI invocations pass T383838-Pci=true.
β€’ Detekt report formats: Detekt.kt checks T383838project.findProperty("ci") == "true" and disables html, txt, md reports in CI; only xml + sarif are retained for GitHub annotations.
β€’ Robolectric SDK caching: The T383838gradle-setup composite action caches T383838~/.m2/repository/org/robolectric to prevent flaky T383838SocketException on SDK downloads. Cache key is T383838robolectric-{version}-sdk{level} β€” update when bumping version or SDK level.
β€’ T383838mavenLocal() gated: Disabled by default to prevent CI cache poisoning. Pass T383838-PuseMavenLocal for local JitPack testing.
β€’ JUnit parallel execution: Enabled project-wide with classes running sequentially (T383838junit.jupiter.execution.parallel.mode.classes.default=same_thread) to avoid T383838Dispatchers.setMain() races. Cross-module parallelism comes from Gradle forks (T383838maxParallelForks).
β€’ T383838test-retry plugin: Applied to all module types (maxRetries=2, maxFailures=10).
β€’ T383838fail-fast: false: Test sharding does not cancel other shards on failure.
β€’ Explicit Gradle task paths: Prefer T383838app:lintFdroidDebug over shorthand T383838lintDebug in CI.
β€’ Pull request CI: Main-only (T383838.github/workflows/pull-request.yml targets T383838main).
β€’ Cache writes: Trusted on T383838main and merge queue runs; other refs use read-only cache.
β€’ Path filtering: T383838check-changes in T383838pull-request.yml must include module dirs plus build/workflow entrypoints (T383838build-logic/**, T383838gradle/**, T383838.github/workflows/**, T383838gradlew, T383838settings.gradle.kts, etc.).
β€’ AboutLibraries: Runs in T383838offlineMode by default (no GitHub/SPDX API calls). Release builds pass T383838-PaboutLibraries.release=true via Fastlane/Gradle CLI to enable remote license fetching. Do NOT re-gate on T383838CI or T383838GITHUB_TOKEN alone.

Served by rngit 1.5.4 - Generated in 0.03s